-- ListMenu
-- 处理列表按钮，包含一二级

local ListViewExtend = import(".ListViewExtend")

local fileName = string.getModeName(...)
local ListMenu = class(fileName)

local string_gsub = string.gsub

-- params
-- list 		 	列表容器，不能为空
-- btnClass 	 	一级按钮类名，不能为空
-- subBtnClass   	二级按钮类名，可以为空
-- operate 		 	操作回调
-- mustHaveTarget 	必须有目标？可以为空
-- onlyOpen 		同一时间只有唯一展开？
-- autoHideSecond	自动隐藏二级菜单（在二级菜单只有一个的时候才会用到）、可以为空（不隐藏）
function ListMenu:ctor( params )
	self._list = params.list
	self._btnClass = params.btnClass
	self._subBtnClass = params.subBtnClass
	self._operate = params.operate
	self._mustHaveTarget = params.mustHaveTarget
	self._onlyOpen = params.onlyOpen
	self._autoHideSecond = params.autoHideSecond

	assert(self._list, "ListMenu.new list can't be nil")
	assert(self._btnClass and self._btnClass ~= "", "ListMenu.new btnClass can't be nil")
	assert(self._subBtnClass and self._subBtnClass ~= "", "ListMenu.new subBtnClass can't be nil")

	self._list:removeAllItems()
	ListViewExtend.scrollToItemExtend(self._list)

	local firstMenu = self._btnClass.create()
	self._firstMenuWidth = firstMenu:getContentSize2()

	local secondMenu = self._subBtnClass.create()
	self._secondMenuHeight = secondMenu:getContentSize().height

	self._curBtn = nil -- 当前选中的一级菜单
	self._curSubBtn = nil -- 当前选中的二级菜单
	self._datas = nil -- 数据源
end

function ListMenu:refreshList( datas )
	self._curBtn = nil 
	self._curSubBtn = nil

	self._datas = datas
	for i, v in ipairs( datas ) do
		self:_createBtn( i, v )
		self:_createSubBtn( i, v.subDatas )
	end
end

function ListMenu:_createBtn( idx, data )
	local btn = self._list:getChildByName( "firstBtn_" .. idx )
	if not btn then
		btn = self._btnClass.create()
		btn:setName( "firstBtn_" .. idx )
		btn:setClickHandler(function( sender )
			self:_btnClick(sender)
		end)
		self._list:pushBackCustomItem( btn )
	end

	btn:setData( data )
	btn:setSelected(false)
end

function ListMenu:_createSubBtn( firstIdx, datas )
	local panel = self._list:getChildByName( "firstPanel_" .. firstIdx )
	if not panel then -- 如果没创建过panel
		panel = ccui.Layout:create()
		panel:setName( "firstPanel_" .. firstIdx )
		self._list:pushBackCustomItem( panel )
	end
	self:_refreshPanelList( panel, datas )

	-- local panelHeight = self._secondMenuHeight * #datas
	-- panel:setContentSize( cc.size( self._firstMenuWidth, panelHeight ) )
end
function ListMenu:_refreshPanelList( panel, datas )
	local panelHeight = self._secondMenuHeight * #datas
	for i, data in ipairs( datas ) do
		local subBtn = panel:getChildByName( "secondBtn_" .. i )
		if not subBtn then
			subBtn = self._subBtnClass.create()
			subBtn:setName( "secondBtn_" .. i )
			subBtn:setClickHandler(function( sender )
				self:_subBtnClick(sender)
			end)
			panel:addChild( subBtn )
		end
		subBtn:setData( data )
		subBtn:setSelected(false)
		subBtn:setPositionY( panelHeight - i * self._secondMenuHeight )
	end
end


function ListMenu:onSelectBtn(btn, ignoreOp)
	if self._curBtn then
		if self._curBtn ~= btn then
			self._curBtn:setSelected(false)-- 之前选中的一级菜单设置不选中
			if self._curBtn.setUnfold then
				self._curBtn:setUnfold(false)
			end
		end
	end

	btn:setSelected(true)
	self._curBtn = btn
	if self._curBtn.setUnfold then
		self._curBtn:setUnfold(true)
	end

	if self._onlyOpen then -- 同一时间只能展开一项
		local btnIdx = string_gsub( btn:getName(), "firstBtn_", "" )
		for i = 1, #self._datas do
			local panel = self._list:getChildByName( "firstPanel_" .. i )
			assert( panel, " -------------->>>>>> 调整panel高度时候取不到对应panel " .. i )
			if i == tonumber( btnIdx ) then -- 当前选中项？
				local panelHeight = 0
				-- 下辖二级菜单有多个，或者没有设置自动隐藏标记
				if 1 < #self._datas[i].subDatas or not self._autoHideSecond then
					panel:setVisible( true )
					panelHeight = self._secondMenuHeight * #self._datas[i].subDatas
				else
					panel:setVisible( false )
				end
				panel:setContentSize( cc.size( self._firstMenuWidth, panelHeight ) )
			else
				panel:setVisible( false )
				panel:setContentSize( cc.size( self._firstMenuWidth, 0 ) )
			end
		end
	end

	self._list:requestRefreshView()
	self._list:forceDoLayout()
	self._list:performWithDelay(function()
		if cc.isAlive(btn) then
			self._list:scrollToItem(btn, 0.8)
		end
	end, 0)

	-- 回掉函数 最后调用
	if not ignoreOp then
		executeFunc(self._operate, "btnClick", btn:getData())
	end
end

--1级菜单的选中
function ListMenu:_btnClick( btn)
	if btn == self._curBtn and btn.setUnfold then
		btn:setSelected(true)
		local isUnfold = btn:isUnfold()
		local btnIdx = string_gsub( btn:getName(), "firstBtn_", "" )
		local panel = self._list:getChildByName( "firstPanel_" .. btnIdx )
		if isUnfold then
			btn:setUnfold(false)
			panel:setVisible( false )
			panel:setContentSize( cc.size( self._firstMenuWidth, 0 ) )
		else
			btn:setUnfold(true)
			panel:setVisible( true )
			for i = 1, #self._datas do
				local panel = self._list:getChildByName( "firstPanel_" .. i )
				assert( panel, " -------------->>>>>> 调整panel高度时候取不到对应panel " .. i )
				if i == tonumber( btnIdx ) then -- 当前选中项？
					local panelHeight = 0
					-- 下辖二级菜单有多个，或者没有设置自动隐藏标记
					if 1 < #self._datas[i].subDatas or not self._autoHideSecond then
						panel:setVisible( true )
						panelHeight = self._secondMenuHeight * #self._datas[i].subDatas
					else
						panel:setVisible( false )
					end
					panel:setContentSize( cc.size( self._firstMenuWidth, panelHeight ) )
				else
					panel:setVisible( false )
					panel:setContentSize( cc.size( self._firstMenuWidth, 0 ) )
				end
			end
		end


		self._list:requestRefreshView()
		self._list:forceDoLayout()
		self._list:performWithDelay(function()
			if cc.isAlive(btn) then
				self._list:scrollToItem(btn, 0.8)
			end
		end, 0)
	else
		self:onSelectBtn(btn)

		if self._mustHaveTarget then -- 必须有目标？
			local btnIdx = string_gsub( btn:getName(), "firstBtn_", "" )
			local firstPanel = self._list:getChildByName( "firstPanel_" .. btnIdx )
			if firstPanel then
				local subBtn = firstPanel:getChildByName( "secondBtn_" .. 1 )
				if subBtn and subBtn ~= self._curSubBtn then
					subBtn:setSelected(true)
					self:_subBtnClick(subBtn)
				end
			end
		end
	end
end

function ListMenu:_subBtnClick(btn, ignoreOp)
	if self._curSubBtn then
		-- print( " --------->>>>>> _curSubBtn ", self._curSubBtn:getData().name )
		self._curSubBtn:setSelected(false)
	end
    --print( " --------->>>>>> btn ", btn:getData().name )
	if btn:isSelected() then -- 操作的btn选中态？
		self._curSubBtn = btn
		if not ignoreOp then
			executeFunc(self._operate, "subBtnClick", btn:getData())
		end
	else
		if self._mustHaveTarget then -- 如果必须要有目标？
			self._curSubBtn = btn
			self._curSubBtn:setSelected(true)
		else
			self._curSubBtn = nil
		end
	end
end

-- 选中特定按钮，并触发操作回调，提供给外部调用(本类里面不能调用)
-- btnIdx 		一级按钮idx, nil(清空状态)
-- subBtnIdx 	二级按钮idx
function ListMenu:selectBtn(btnIdx, subBtnIdx, ignoreOp)
	local btn = self._list:getChildByName( "firstBtn_" .. btnIdx )
	if btn and btn ~= self._curBtn then
		-- btn:setSelected(true)
		-- self:_btnClick(btn, ignoreOp)
		self:onSelectBtn(btn, ignoreOp)
	end
	if subBtnIdx then
		local firstPanel = self._list:getChildByName( "firstPanel_" .. btnIdx )
		if firstPanel then
			local subBtn = firstPanel:getChildByName( "secondBtn_" .. subBtnIdx )
			if subBtn and subBtn ~= self._curSubBtn then
				subBtn:setSelected(true)
				self:_subBtnClick(subBtn, ignoreOp)
			end
		else
			print( " --------->>>>> 一级菜单对应的Panel不存在 ", btnIdx )
		end
	end
end


function ListMenu:getMenuItem(idx)
	return self._list:getChildByName( "firstBtn_" .. idx )
end

function ListMenu:setBtnRedPoint(btnIdx, subBtnIdx, isShow)
	local targetBtn = nil
	if not subBtnIdx or subBtnIdx <= 0 then
		targetBtn = self._list:getChildByName( "firstBtn_" .. btnIdx )
	else
		local panel = self._list:getChildByName( "firstPanel_" .. btnIdx )
		if panel then 
			targetBtn = panel:getChildByName( "secondBtn_" .. subBtnIdx )
		end
	end

	if targetBtn and targetBtn.setRedPoint then
		targetBtn:setRedPoint(isShow)
	end
end

function ListMenu:removeAllMenus()
	self._list:removeAllItems()
	ListViewExtend.scrollToItemExtend(self._list)
end

function ListMenu:remove()
	self._list = nil
	self._btnClass = nil
	self._subBtnClass = nil
	self._operate = nil
	self._mustHaveTarget = nil
	self._onlyOpen = nil
	self._firstMenuWidth = nil
	self._secondMenuHeight = nil
	self._curBtn = nil -- 当前选中的一级菜单
	self._curSubBtn = nil -- 当前选中的二级菜单
	self._datas = nil
end

return ListMenu
